<?php
namespace app\api\controller\xiluedu;


use addons\xiluedu\controller\WeixinMini;
use addons\xiluedu\controller\WeixinPublic;
use app\common\controller\Api;
use app\common\library\Sms;
use app\common\model\ScoreLog;
use app\common\model\xiluedu\FooterView;
use app\common\model\xiluedu\SignPoster;
use app\common\model\xiluedu\Third;
use app\common\model\xiluedu\UserCollection;
use app\common\model\xiluedu\UserCoupon;
use app\common\model\xiluedu\UserCourse;
use app\common\model\xiluedu\UserMessageAccount;
use app\common\model\xiluedu\UserStudy;
use app\common\model\xiluedu\UserVip;
use EasyWeChat\Kernel\Exceptions\DecryptException;
use fast\Random;
use PHPQRCode\QRcode;
use think\Cookie;
use think\Db;
use think\Exception;
use think\exception\ThrowableError;
use think\Hook;
use think\Session;
use think\Validate;
use function fast\array_get;

/**
 * 用户模块控制器
 */
class User extends Api
{
    protected $noNeedLogin = ['wxlogin','get_mobile','mobilelogin','auth'];
    protected $noNeedRight = ['*'];


    public function wxlogin()
    {
        $param = $this->request->only(['code','platform']);
        $platform = array_get($param,'platform','wxmini');
        $wx = new WeixinMini();
        try {
            switch ($platform){
                case 'wxmini':
                    $config = \app\common\model\xiluedu\Config::getMyConfig('wxmini');
                    if(!$config || !$config['wxmini_appid'] || !$config['wxmini_appid']){
                        throw new Exception("请正确配置微信信息");
                    }
                    $data = $wx->wxlogin($param['code']);
                    $third = Third::where('platform',$platform)->where('openid',$data['openid'])->find();
                    if(!$third){
                        $third_data = [
                            'platform'      =>  $platform,
                            'user_id'       =>  0,
                            'openname'      =>'',
                            'openid'        =>  $data['openid'],
                            'unionid'      =>  $data['unionid'] ?? '',
                            'access_token'  =>  $data['session_key'],
                            'logintime'     =>  time()
                        ];
                        $third = Third::create($third_data);
                    }else{
                        $third_data = [
                            'access_token'  =>  $data['session_key'],
                            'unionid'      =>  $data['unionid'] ?? '',
                            'logintime'     =>  time()
                        ];
                        if($third->user_id>0){
                            $user = \app\common\model\User::get(['id'=>$third->user_id]);
                            if(!$user){
                                $third_data['user_id'] = 0;
                            }
                        }
                        $third->save($third_data);
                    }
                    if($third->user_id>0){
                        #模拟登陆
                        $this->auth->direct($user->id);
                        $userinfo = $this->auth->getUserinfo();
                        $data = ['userinfo' => $userinfo];
                        $data['third'] = ['third_id'=>$third->id,'openname'=>$third->openname,'binding'=>1];
                    }else{
                        $data = ['userinfo'=>[]];
                        $data['third'] = ['third_id'=>$third->id,'openname'=>$third->openname,'binding'=>0];
                    }
                    break;
                case 'wxpublic':

                    break;
            }
        }catch (ThrowableError $e){
            $this->error($e->getMessage());
        }catch (Exception $e){
            $this->error($e->getMessage());
        }
        $this->success('获取session_key成功',$data);

    }

    /**
     * 网页授权
     */
    public function auth(){
        $target_url = $this->request->param('target_url',null,null);
        if(Cookie::get('token') && $this->auth->getUser()){
            $target = explode('?',$target_url);
            if(count($target) > 1){
                $domain = $target[0];
                $query = $target[1].'&token='.Cookie::get('token');
                $target_url = $domain.'?'.$query;
            }else{
                $target_url .= '?token='.Cookie::get('token');
            }
            header('location:'.$target_url);
        }else{
            Session::set('target_url',$target_url);
            (new WeixinPublic())->auth();
        }
    }
    /**
     * @ApiTitle (获取手机号)
     * @ApiParams (name="third_id", type="int", required=true, description="第三方id")
     * @ApiParams (name="code", type="string", required=true, description="code")
     */
    public function get_mobile()
    {
        $param = $this->request->only(['third_id','code']);
        $iv = $this->request->param('iv',null,null);
        $encryptedData = $this->request->param('encryptedData',null,null);
        $wx = new WeixinMini();
        $third = Third::where('id',array_get($param,'third_id'))->find();
        if(!$third) $this->error('未找到third数据',[],40001);
        if($third->user_id>0){
            $user = \app\common\model\User::get($third->user_id);
            if($user){
                $this->auth->direct($third->user_id);
                $third = ['third_id'=>$third->id,'binding'=>1];
                $this->success('手机号已经注册成功',['userinfo'=>$this->auth->getUserinfo(),'third'=>$third]);
            }
        }

        Db::startTrans();
        try {
            //新版本授权
            if($code = array_get($param,'code')){
                $data = $wx->getPhoneNumber($code);
            }else if($iv && $encryptedData){
                $data = $wx->wxEncrypted($third['access_token'],$iv,$encryptedData);
            }else{
                throw new Exception("获取手机号参数错误");
            }
            if(!$data){
                throw new Exception("获取手机号失败");
            }
            $user = \app\common\model\User::where('mobile',$data['phoneNumber'])->find();
            if ($user) {
                if ($user->status != 'normal') {
                    $this->error(__('Account is locked'));
                }
                //如果已经有账号则直接登录
                $ret = $this->auth->direct($user->id);
            } else {
                $user_config = \app\common\model\xiluedu\Config::getMyConfig('user');
                $extend = [];
                if(isset($user_config['avatar'])){
                    $extend['avatar'] = cdnurl($user_config['avatar'],true);
                }
                $ret = $this->auth->register($data['phoneNumber'], Random::alnum(), '', $data['phoneNumber'], $extend);
            }
            if ($ret) {
                $userinfo = $this->auth->getUserinfo();
                #更新third表字段
                $third->user_id = $userinfo['id'];
                $third->save();
                #创建用户消息表
                UserMessageAccount::addAccount($userinfo['id']);
                $third = ['third_id'=>$third->id,'binding'=>1];
                $data = ['userinfo' => $userinfo,'third'=>$third];
            } else {
                $this->error($this->auth->getError());
            }
        }catch (ThrowableError $e){
            Db::rollback();
            $this->error($e->getMessage());
        }catch (Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }
        Db::commit();
        $this->success(__('登录成功'), $data);
    }

    /**
     * 微信基本信息解密
     * @ApiParams (name="third_id", type="int", required=true, description="第三方id")
     * @ApiParams (name="iv", type="string", required=true, description="iv")
     * @ApiParams (name="encryptedData", type="string", required=true, description="encryptedData")
     */
    public function wxdecrypt()
    {
        $param = $this->request->only(['platform']);
        $iv = $this->request->param('iv',null,null);
        $encryptedData = $this->request->param('encryptedData',null,null);
        $wx = new WeixinMini();
        $platform = array_get($param,'platform','wxmini');
        $third = Third::where('user_id',$this->auth->id)->where('platform',$platform)->find();
        if(!$third || $third->user_id <= 0) {
            $this->error('未找到登录信息',[],40001);
        }
        Db::startTrans();
        try {
            $encrypted = $wx->wxEncrypted($third['access_token'],$iv,$encryptedData);
            if ($encrypted) {
                $user = $this->auth->getUser();
                #更新登录表的三方昵称头像
                $third->openname = $encrypted['nickName'];
                $third->avatar = $encrypted['avatarUrl'];
                $third->save();
                $user->nickname = $encrypted['nickName'];
                $user->avatar = $encrypted['avatarUrl'];
                $user->gender = $encrypted['gender'];
                $user->save();
            } else {
                $this->error("获取用户数据失败");
            }
        }catch (DecryptException $e){
            Db::rollback();
            $this->error($e->getMessage());
        }catch (ThrowableError $e){
            Db::rollback();
            $this->error($e->getMessage());
        }catch (Exception $e){
            Db::rollback();
            $this->error($e->getMessage());
        }
        Db::commit();
        $this->success(__('获取用户基本数据成功'));
    }

    /**
     * @ApiTitle (修改会员个人信息)
     * @ApiRoute (/api/xiluedu.user/profile)
     * @ApiMethod (POST)
     * @ApiHeaders (name=token, type=string, require=true, description="Token")
     * @ApiParams (name="avatar", type="string", required=true, description="头像")
     * @ApiParams (name="nickname", type="string", required=true, description="昵称")
     */
    public function profile()
    {
        $user = $this->auth->getUser();
        $user->visible(['email','avatar','nickname']);
        if($this->request->isPost()) {
            $email = $this->request->post('email');
            $nickname = $this->request->post('nickname');
            $avatar = $this->request->post('avatar', '', 'trim,strip_tags,htmlspecialchars');
            $user->nickname = $nickname;
            $user->avatar = $avatar;
            if ($email) {
                $exists = \app\common\model\User::where('email', $email)->where('id', '<>', $this->auth->id)->find();
                if ($exists) {
                    $this->error(__('邮箱已存在'));
                }
                $user->email = $email;
            }
            $user->save();
            $this->success('', ['profile'=>$user]);
        }
        $this->success('',['profile'=>$user]);
    }

    /**
     * 手机验证码登录
     *
     * @ApiMethod (POST)
     * @param string $mobile  手机号
     * @param string $captcha 验证码
     */
    public function mobilelogin()
    {
        $mobile = $this->request->post('mobile');
        $captcha = $this->request->post('code');
        if (!$mobile || !$captcha) {
            $this->error(__('Invalid parameters'));
        }
        if (!Validate::regex($mobile, "^1\d{10}$")) {
            $this->error(__('手机号格式错误'));
        }
        if (!Sms::check($mobile, $captcha, 'mobilelogin')) {
            $this->error(__('验证码错误'));
        }
        $user = \app\common\model\User::getByMobile($mobile);
        if ($user) {
            if ($user->status != 'normal') {
                $this->error(__('账号已被锁定'));
            }
            //如果已经有账号则直接登录
            $ret = $this->auth->direct($user->id);
        } else {
            $ret = $this->auth->register($mobile, Random::alnum(), '', $mobile, []);
        }
        if ($ret) {
            Sms::flush($mobile, 'mobilelogin');
            $userinfo = $this->auth->getUserinfo();
            #创建用户消息表
            UserMessageAccount::addAccount($userinfo['id']);
            $data = ['userinfo' => $userinfo];
            $this->success(__('Logged in successful'), $data);
        } else {
            $this->error($this->auth->getError());
        }
    }


    /**
     * 用户信息
     */
    public function info(){
        $user = $this->auth->getUser()->hidden(['group_id','password','salt','level','bio','token','loginip','joinip','jointime','successions','maxsuccessions','prevtime']);
        $user['coupon_count'] = UserCoupon::getCouponCount(['coupon.status'=>1,'coupon.use_end_time'=>['lt',time()],'user_coupon.user_id'=>$user->id]);
        $user['footer_count'] = FooterView::getViewCount(['user_id'=>$user->id]);
        $user_vip = UserVip::where('user_id',$user->id)->find()?:[];
        $vip_status = false;
        if($user_vip && $user_vip['expire_time'] >= strtotime(date('Y-m-d'))){
            $vip_status = true;
        }
        $user_message_account = UserMessageAccount::where('user_id',$user->id)->find();
        $user['message_count'] = $user_message_account['activity_message'] + $user_message_account['system_message']+$user_message_account['user_message'];
        $user['mobile'] = substr_replace($user['mobile'],'****',3,4);
        $user['vip_status'] = $vip_status;
        $user['user_vip'] = $user_vip;
        $this->success('查询成功',$user);
    }

    /**
     * 我的优惠券
     */
    public function coupon_lists(){
        $params = $this->request->param('');
        $this->success('查询成功',UserCoupon::get_user_coupon($params));
    }


    /**
     * 我的课程列表
     */
    public function course_lists(){
        $params = $this->request->param('');
        $this->success('查询成功',UserCourse::lists($params));

    }

    /**
     * 我的课程收藏列表
     */
    public function course_collection(){
        $params = $this->request->param('');
        $this->success('查询成功',UserCollection::lists($params,UserCollection::TYPE_COURSE));

    }


    /**
     * 足迹
     */
    public function footer_view(){
        $params = $this->request->param('');
        $this->success('查询成功',FooterView::lists($params));
    }

    /**
     * 我的积分日志
     */
    public function score_lists(){
        $params = $this->request->param('');
        $tab = array_get($params,'tab',0);
        if($tab > 0){
            $where['score'] = ['lt',0];
        }else{
            $where['score'] = ['gt',0];
        }
        $pagesize = array_get($params,'pagesize');
        $lists = ScoreLog::where('user_id',$this->auth->id)->where($where)->order('id','desc')->paginate($pagesize);

        $this->success('查询成功',$lists);

    }

    /**
     * 打卡海报
     */
    public function poster(){
        $lists = SignPoster::where('status',1)->orderRaw("RAND()")->find();
        if(!$lists){
            $this->success('查询成功',[]);
        }
        $platform = $this->request->param('platform','wxmini');
        $root = '.';
        $filename = md5(mt_rand()).'.png';
        if(!get_addon_config('alioss')){
            $path = "/uploads/".date('Ymd').'/';
        }else{
            $path = "/xiluedu/".date('Ymd').'/';
        }
        if (!file_exists($root . $path)) {
            @mkdir($root . $path, 0777, true);
        }
        $qrcode = $path.$filename;

        if($platform == 'h5'){
            QRcode::png(request()->domain().'/h5/#/pages/index/index?user_id='.$this->auth->id, $root.$qrcode, 'L', 6, 2);
            $lists->qrcode = request()->domain().$qrcode;
        }else{
            $wxmini = new WeixinMini();
            $res = $wxmini->getUnlimited('user_id='.$this->auth->id,'pages/index/index');
            if($res){
                if(!get_addon_config('alioss')){
                    file_put_contents($root.$qrcode,$res);
                }else{
                    Common::uploadAlioss($qrcode, $res);
                }
                $lists->qrcode = cdnurl($qrcode,true);
            }
        }
        $this->success('查询成功',$lists);

    }

    /**
     * 打卡语录
     */
    public function sentence(){
        $lists = db('xiluedu_sign_sentence')->where('status',1)->order("id",'asc')->select();
        $this->success('查询成功',$lists);

    }

    /**
     * 学习成就
     */
    public function study(){
        $view_time = UserStudy::where('user_id',$this->auth->id)->sum('view_time')?:0;
        $view_count = UserStudy::where('user_id',$this->auth->id)->group('course_id')->count('id')?:0;
        $h = floor($view_time/3600);
        $m = floor(($view_time-$h*3600)/60);
        $s = $view_time - $h*3600 - $m*60;
        $view_time = $h.'时'.$m.'分'.$s.'秒';
        $pagesize = $this->request->param('pagesize',10);
        $lists = UserStudy::with(['course'=>function($query){
            $query->withField(['id','type','name','category_id','tag_ids','teacher_id','thumb_image','description','is_charge','(basic_num+real_num) total_num','collection_count','salesprice']);
        }])->where('user_id',$this->auth->id)->group('course_id')->order('updatetime','desc')->paginate($pagesize);
        $lists = $lists->toArray();
        $lists['view_time'] = $view_time;
        $lists['view_count'] = $view_count;
        $this->success('ok',$lists);
    }

    /**
     * 线下学习
     */
    public function study_offline(){
        $count = \app\common\model\xiluedu\OfflineOrder::where('user_id',$this->auth->id)->count('id')?:0;

        $pagesize = $this->request->param('pagesize',10);
        $lists = \app\common\model\xiluedu\OfflineOrder::where('user_id',$this->auth->id)->where('pay_status',0)->order('updatetime','desc')->paginate($pagesize);
        $lists = $lists->toArray();
        $lists['offline_count'] = $count;
        $this->success('ok',$lists);
    }

}